//
//  ModuleContainer.cpp
//  sad
//
//  Created by Christopher Kemsley on 1/31/12.
//  Copyright (c) 2012 iAppolopolis. All rights reserved.
//



#include "ModuleFactory.hpp"
#include "SystemCDefinitions.hpp"
#include <vector>
#include "PubSub.hpp"

#include "Settings.hpp"
#include "Codec.hpp"

#include "Log.hpp"
#include "URL.hpp"

#include "Exception.hpp"




struct ContainerSettings : public Settings
{
	std::vector<ModelVariant>		variants ;
	
	ContainerSettings ( std::string const & name )
	:	Settings(name)
	,	variants()
		{
		add ( "modules" , variants ) ;
		}
	
	virtual void	validate ()
		{
		if ( variants.size() == 0 )
			throw Exception ( "ContainerSettings" , "No variants found in container's settings" , __FILE__,__LINE__ ) ;
		}
} ;





class	ModuleContainer : public ConfiguredModel<ContainerSettings>
{
public:
	
	std::vector<Model*>	mModules ;
	
	
	ModuleContainer	( ModelVariant const & identity )
	:	ConfiguredModel<ContainerSettings>		( identity )
	,	mModules	()
		{
		/** Initialize modules **/
		_init_modules () ;
		}
	virtual ~ModuleContainer	()
		{
		std::vector<Model*>::iterator	here	=	mModules.begin() ;
		std::vector<Model*>::iterator	end		=	mModules.end() ;
		while ( here < end )	delete *(here++) ;
		}
	
	
	
	
	
	
	void	_init_modules ()
		{
		std::vector<ModelVariant>::iterator	here	=	mConfig.variants.begin() ;
		std::vector<ModelVariant>::iterator	end		=	mConfig.variants.end() ;
		while ( here < end )
			{
			ModelVariant & variant = *(here++) ;
			Log::states("ModuleContainer") << "Building: " << variant ;
			Model * mod = ModuleFactory :: create ( variant ) ;
			if ( mod != 0 )
				mModules . push_back ( mod ) ;
			else
				Log::error("ModuleContainer") << "*** Failed to create " << variant ;
			}
		}
	
} ;




TypedModuleMaker<ModuleContainer>	_ModuleContainer ( "Container" ) ;
